public without sharing class OppAboradController {

	public String backId {private set; get;}
	public String msg  {private set; get;}
	public Boolean isErr {private set; get;}
	public Boolean isSuccess {private set; get;}
	public  Boolean isNew {private set; get;}
	private Map<String,DataUtil.SObjectBean> stageObjectMap ; 
    public class ControllerException extends Exception {}
	public Opportunity opp {get ;set ;}
    public Boolean isDrop {private set; get; }

    public String dataJson {get; private set;}
    public String saveJson {get;  set;}

    public String currentStage {get; private set;}

    public String searchJson {get; set;}

    public OppAboradController() {
        opp = new Opportunity();
        backId = System.currentPageReference().getParameters().get('id');
        stageObjectMap = new  Map<String,DataUtil.SObjectBean>();
        isDrop =  System.currentPageReference().getParameters().get('drop') != null;
        isNew = false ;

    }

    public void init(){


    	try {


    	    Map<String,Object> dataMap  = new Map<String ,Object>();
    	    if(backId == null){
    	    	setError('页面打开错误!');
    	    }else if(Id.valueOf(backId).getSobjecttype() == Account.SObjectType ){

    	    	opp.AccountId = backId;
                Account acc = [select Status__c from Account where Id =:backId];
                if(acc.Status__c != '审核通过')setError('客户未审批通过不能新建业务机会!联系管理员审批!');
    	    	isNew = true ;
    	    	currentStage = '';


    	    }else if(Id.valueOf(backId).getSobjecttype() == Opportunity.SObjectType ){
    	   		/* dataMap.put('base',getOpp(backId));
	    		if(opp.StageName == '意向'){
	    			dataMap.put('dept',getDeptInfo());
	    			dataMap.put('contact',getContactInfo());
	    		}
	    		currentStage = opp.StageName ;*/
	    		opp = [select Id ,AccountId ,StageName from Opportunity where Id=:backId];

                if( opp.StageName == '失败' || opp.StageName == '关闭') setError('业务机会已丢单!不能操作!');
            
	    		currentStage = opp.StageName;
                if(!isDrop && (opp.StageName == '市场管理' || opp.StageName == '提起合作确认' || opp.StageName== '失败'))setError('业务机会'+opp.StageName +'阶段不能点击下阶段!');
                if(isDrop && (opp.StageName == '市场管理' || opp.StageName == '提起合作确认' || opp.StageName== '失败'))setError('业务机会'+opp.StageName +'阶段不能丢单!');
    	    }

    	    
	    	 //字段
	    	 Map<String,Set<String>> fieldsmap = getFields();
	    	 System.debug('OppAboradController==>'+fieldsMap);
	    	 //字段详情
	    	 Map<String, List<DataUtil.FieldBean>> fbMap = DataUtil.getFieldsBean(fieldsmap,stageObjectMap);
	    	 System.debug('OppAboradController==>'+fbMap);
	    	//字段赋值
	    	 Map<String,List<DataUtil.FieldBean>> fields = DataUtil.setFieldsValue(fbMap,DataUtil.getBaseInfo(fbMap,stageObjectMap) );
	    	 System.debug('OppAboradController==>'+fields);
             System.debug('OppAboradController==>'+stageObjectMap);

	 		dataMap.put('base',fields);
    		dataMap.put('baseObject',DataUtil.getBaseObjectMap(stageObjectMap)); 

    		dataMap.put('detailObject',getDetailObject()); 
    		dataMap.put('searchObject',getSearchObject()); 

    		dataMap.put('intent', getIntentDetail(backId));
    		dataMap.put('cpprice',getCompetitorPrice());

    		dataJson = EncodingUtil.urlEncode(JSON.serialize(dataMap), 'UTF-8');
           // if(currentStage =='市场沟通' && ([select count() from Quote where OpportunityId =:opp.Id and Status in ('申请中','已批准','已拒绝') ] == 0 ))setError('没有有提交中/审批成功/审批拒绝的报价!请先处理报价!');
    	}catch (Exception e) {
    	    
    	    ApexPages.addMessage( new ApexPages.Message(ApexPages.Severity.ERROR ,e.getMessage()));

    	}

    }

    public void save(){
    	msg = '';

        if( !isDrop && currentStage =='市场沟通' && ([select count() from Quote where OpportunityId =:opp.Id and Status in ('申请中','已批准','已拒绝') ] == 0 )){
            msg = '没有有提交中/审批成功/审批拒绝的报价!请先处理报价!';
            return;
        }
    	Map<String,Object> saveMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson, 'UTF-8'));

    	List<IntentProduct__c> ipList = new List<IntentProduct__c>();
    	if(saveMap.containsKey('intent')){
    		List<Object> intents = (List<Object>)saveMap.get('intent');
    		for(Object o :intents){
    			Map<String,Object> mo = (Map<String,Object>) o;
    			IntentProduct__c ip = new IntentProduct__c();
    			ip.Product__c =DataUtil.getStringValue( mo.get('productId'));
    			ip.CompetitorCompany__c = DataUtil.getStringValue( mo.get('cpcompany'));
    			ip.CompetitorBrand__c = DataUtil.getStringValue( mo.get('cpbrand'));
    			ip.CompetitorProduct__c = DataUtil.getStringValue( mo.get('cpproduct'));
    			ip.ContractForm1__c = DataUtil.getStringValue( mo.get('coopmode'));
    			ipList.add(ip);
    		}

    	}
    	List<CompetitorPrice__c> cpList = new List<CompetitorPrice__c>();
    	if(saveMap.containsKey('cpprice')){
            //客户 的国家
             Account acc = [select Id ,Country__c from Account where Id =:opp.AccountId ];
            Map<String,Id > indMap = new Map<String,Id>();
            for(IVDProductLineMarket__c ind : [select Id ,ProductLine__c from IVDProductLineMarket__c where Country__c =:acc.Country__c ]){

                indMap.put(ind.ProductLine__c, ind.Id);
            }

    		List<Object> cpprices = (List<Object>)saveMap.get('cpprice');
    		for(Object o :cpprices){
    			Map<String,Object> mo = (Map<String,Object>) o;
    			CompetitorPrice__c cp = new CompetitorPrice__c();
    			cp.Product__c = DataUtil.getStringValue(mo.get('product'));

    			cp.ProductLine__c = DataUtil.getStringValue(mo.get('productLineId'));
                if(cp.ProductLine__c == null || String.valueOf(cp.ProductLine__c).length() == 0 ) cp.ProductLine__c = indMap.get(DataUtil.getStringValue(mo.get('productLineName')));
                if(cp.ProductLine__c == null ||  String.valueOf(cp.ProductLine__c).length() == 0){

                    msg = '请维护IDV市场产品线!';
                    return;
                }
    			cp.Manufactor__c = DataUtil.getStringValue(mo.get('brandId'));
    			cp.Agent__c = DataUtil.getStringValue(mo.get('agent'));
    			cp.TerminalPrice__c  = DataUtil.getStringValue(mo.get('terprice'));
    			cp.DistributorPrice__c = DataUtil.getStringValue(mo.get('dealerprice'));
    			cp.PriceSource__c = DataUtil.getStringValue(mo.get('pricesource'));
               
    			cpList.add(cp);

    		}
    	}


    	List<SObject> soList = new List<SObject>();
    	if(saveMap.containsKey('base')){
    		Map<String,Object> baseMap = (Map<String,Object>) saveMap.get('base');

			for(String objname : stageObjectMap.keySet()){

				Map<String,Object> dataMap = (Map<String,Object> ) baseMap.get(objname);
				DataUtil.SObjectBean sb  = stageObjectMap.get(objname);
                System.debug('stageObjectMap==>'+objname+'='+sb.idvalue);

				SObject so = sb.stype.newSObject();
				if(isNew && objname =='Opportunity'){
					so.put('StageName', '意向');
	                so.put('Name', '系统设置');
					so.put('AccountId', opp.AccountId);

    	    			//opp.RecordTypeId = Utils.getRecordTypeIdByDevNameAndObjName('OverseaDearlerOpportunity	', 'Opportunity');
					so.put('RecordTypeId',Utils.getRecordTypeIdByDevNameAndObjName('OverseaDearlerOpportunity', 'Opportunity'));
				}else{
                    if(isDrop && objname =='Opportunity' ) so.put('StageName','失败');
                    if(sb.idvalue != null ) so.put('Id', sb.idvalue);
                }
				Map<String,Set<String>> fieldsMap = getFields();
				Map<String,DataUtil.FieldBean> fbeanMap = DataUtil.getFieldsInfo(sb.stype,fieldsMap.get(objname));
				for(String field : fieldsMap.get(objname)){
					so.put(field, DataUtil.dataHandler(dataMap.get(field),fbeanMap.get(field).type.toUpperCase() ));
				}
                System.debug(sb.idvalue);
				soList.add(so);
			}
    	}


    	SavePoint sp = Database.setSavepoint();
    	try {
    		if(soList.size() > 0){
    			for(SObject so : soList ){
    				if(so.get('Id') != null ){
    			         System.debug('OppAboradController==>'+so +' '+opp.StageName);
    					update so ;
    				}else{
    					insert so ;
    					if(isNew) backId = String.valueOf(so.get('Id'));
    					if(Id.valueOf(backId).getSObjecttype() == Opportunity.SObjectType )opp.Id = backId;
    				}
    			}
    		}

            if(isDrop){

                isSuccess = true; 
                msg = '丢单成功!';
                return;
            }

    		if(!isNew){
    			if(currentStage =='意向')opp.StageName = '市场沟通';
    			if(currentStage =='市场沟通')opp.StageName = '合作细节谈判' ;
    			if(currentStage =='合作细节谈判')opp.StageName = '提起合作确认' ;
    			if(currentStage =='提起合作确认')opp.StageName = '市场管理' ;
    			System.debug('OppAboradController==>'+currentStage +' '+opp.StageName);
    			update opp;

    		}
    		for(IntentProduct__c ip: ipList){
    			ip.Opportunity__c = opp.Id ; 
    		}

    		delete [select Id from IntentProduct__c where Opportunity__c =:opp.Id];
    		if(ipList.size() > 0 ) insert ipList;
    		delete [select Id from CompetitorPrice__c where Opportunities__c =:opp.Id];
            for(CompetitorPrice__c cp : cpList){
                cp.Opportunities__c = opp.Id;
            }
    		if(cpList.size() > 0) insert cpList;
    	    isSuccess = true; 
    	    msg = '保存成功!'; 
    	}catch (Exception e) {
    	    
    	    Database.rollback(sp);
    	    msg = '保存失败!'+e.getMessage() +e.getStackTraceString();
    	    if(isNew){
    	    	opp.Id = null; 
    	    }
    	}	
    	
    }

    private Map<String,List<DataUtil.FieldBean>> getSearchObject(){
    	Map<String,List<DataUtil.FieldBean>> searchMap = new Map<String,List<DataUtil.FieldBean>>();

    	Map<String,DataUtil.FieldBean>proMap = DataUtil.getFieldsInfo(Product__c.SObjecttype, new Set<String>{'ProductName__c','Brand__c','Spec__c','SerialNo__c','Category0__c'} );
    	searchMap.put('Product__c', proMap.values());
    	return searchMap;
    }

    private Map<String,List<DataUtil.FieldBean>> getDetailObject(){
    	Map<String,List<DataUtil.FieldBean>> detailMap = new Map<String,List<DataUtil.FieldBean>>();

    	Map<String,DataUtil.FieldBean>tmp  =  DataUtil.getFieldsInfo(IntentProduct__c.SObjecttype, new Set<String>{'ContractForm1__c'} );
    	detailMap.put('IntentProduct__c', tmp.values());

        Map<String,DataUtil.FieldBean>tmp1  =  DataUtil.getFieldsInfo(IVDProductLineMarket__c.SObjecttype, new Set<String>{'ProductLine__c'} );
        detailMap.put('IVDProductLineMarket__c', tmp1.values());
        
    	return detailMap;
    }

    //获取意向产品
    private List<IntentBean> getIntentDetail(String opp_id ){
    	List<IntentBean>  tmp = new  List<IntentBean>();
    	if(opp_id != null && Id.valueOf(backId).getSobjecttype() == Opportunity.SObjectType){
    		for(IntentProduct__c ip :[select Id ,Product__c ,ContractForm1__c,CompetitorCompany__c,Product__r.Category1__c,
    			CompetitorBrand__c,CompetitorProduct__c,Product__r.ProductName__c,Product__r.Category0__c,Product__r.NCCode__c , 
    			Product__r.Spec__c,Product__r.SerialNo__c  from IntentProduct__c where 
    			Opportunity__c =:opp_id]){
    			tmp.add(new IntentBean(ip));
    		}
    	}
    	return tmp;
     
    }

    //获取竞争对手产品线价格
    private List<CompetitorPriceBean> getCompetitorPrice(){
    	//
    	
    	//当前 国家 的 IVD各产品线市场
    	//List<IVDProductLineMarket__c>  ivdList = [select Id ,ProductLine__c from IVDProductLineMarket__c where Country__c =:acc.Country__c ];
        

    	Map<String,CompetitorPriceBean> tmpMap = new Map<String,CompetitorPriceBean> ();
    	//当前 业务机会的 竞争对手产品线价格
    	if(opp.Id != null){
    		for(CompetitorPrice__c cp:  [select Id,Product__c,ProductLine__c,ProductLine__r.ProductLine__c,Agent__c,PriceSource__c,
    		Manufactor__c,Manufactor__r.Name,Opportunities__c,TerminalPrice__c,DistributorPrice__c
    		 from CompetitorPrice__c where Opportunities__c =:opp.Id ]){
    			 tmpMap.put(cp.ProductLine__r.ProductLine__c,new CompetitorPriceBean(cp));
    		}
    		
    	}
    	return tmpMap.values();

    }

    //设置错误
    private void setError(String message){
    	isErr = true;
      throw new ControllerException(message);

    }
    public void setNil(){
    	dataJson = '[]';
    	searchJson = '{}';
    	saveJson = '{}';

    }
    public void search (){
    	Map<String,Object> searchMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(searchJson,'UTF-8'));

    	String sql = ' select Id ,ProductName__c ,SerialNo__c ,NCCode__c, Brand__c ,Spec__c,Category1__c,Category0__c from Product__c where  Createddate != null and (Overseasproducts__c  = true  or Brand__c in '+MaccuraBrandUtil.getMaccuraInStr()+ ')  ';
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('ProductName__c'))) == false) sql += ' and ProductName__c like \'%'+DataUtil.getStringValue(searchMap.get('ProductName__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Brand__c'))) == false) sql += ' and Brand__c like \'%'+DataUtil.getStringValue(searchMap.get('Brand__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Spec__c'))) == false) sql += ' and Spec__c like \'%'+DataUtil.getStringValue(searchMap.get('Spec__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('SerialNo__c'))) == false) sql += ' and SerialNo__c like \'%'+DataUtil.getStringValue(searchMap.get('SerialNo__c'))+'%\' ';
 
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category0__c'))) == false) sql += ' and Category0__c like \'%'+DataUtil.getStringValue(searchMap.get('Category0__c'))+'%\' ';

    	sql += ' limit 200 ';
    	List<IntentBean> tmp = new List<IntentBean>();
    	for(Product__c p: Database.query(sql)){
    		tmp.add(new IntentBean(p));
    	}

    	dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');


    }

    public Map<String,Set<String>>  getFields(){
    	Map<String,Set<String>> fieldsMap  = new  Map<String,Set<String>>();
    	
        if(isDrop){
            DataUtil.SObjectBean sb = new DataUtil.SObjectBean();

            sb.title ='业务机会基本信息';
            sb.objname = 'Opportunity';
            sb.stype = DataUtil.getSObjectType('Opportunity');
            if(opp.Id != null )sb.idvalue = opp.Id ;
            sb.type = 'base';
            if(opp.Id != null )sb.condition = ' where Id =\''+opp.Id+'\'';
            stageObjectMap.put('Opportunity',sb );

             Set<String>  fields = new Set<String>{'LostReason__c','Successfulcompany__c','Winningcompanychannel__c','LostReasoneDesc__c','SuccessfulModel__c','WhetherParticipate__c','ContractTime__c','SuccessfulBrand__c'};
            fieldsMap.put('Opportunity', fields);

        }else if(currentStage == '合作细节谈判'){
            DataUtil.SObjectBean sb = new DataUtil.SObjectBean();

            sb.title ='业务机会基本信息';
            sb.objname = 'Opportunity';
            sb.stype = DataUtil.getSObjectType('Opportunity');
            sb.idvalue = opp.Id ;
            sb.type = 'base';
            sb.condition = ' where Id =\''+opp.Id+'\'';
            stageObjectMap.put('Opportunity',sb );

             Set<String>  fields = new Set<String>{'AgentInput__c','SpreadSPlan__c','MacSupport__c','RegisteredSituation__c','ImportantNotify__c'};
            fieldsMap.put('Opportunity', fields);
        } else{
            DataUtil.SObjectBean sb = new DataUtil.SObjectBean();

            sb.title ='业务机会基本信息';
            sb.objname = 'Opportunity';
            sb.stype = DataUtil.getSObjectType('Opportunity');
            if(opp.Id != null )sb.idvalue = opp.Id ;
            sb.type = 'base';
            if(opp.Id != null )sb.condition = ' where Id =\''+opp.Id+'\'';
            stageObjectMap.put('Opportunity',sb );

             Set<String>  fields = new Set<String>{'ProjStartDate__c','CloseDate'};
            fieldsMap.put('Opportunity', fields);

            if(isNew){

                 DataUtil.SObjectBean accsb  = new DataUtil.SObjectBean();

                accsb.title ='客户基本信息';
                accsb.objname = 'Account';
                accsb.stype = DataUtil.getSObjectType('Account');
                accsb.idvalue = opp.AccountId   ;
                accsb.type = 'base';
                accsb.condition = ' where Id =\''+opp.AccountId +'\'';
                stageObjectMap.put('Account',accsb );

                 Set<String>  accfields = new Set<String>{'FutureDevelopmentStrategy__c','Country__c','Address__c','PersonStructure__c','TotalSalesAndProductPercent__c','MainProductAndCooperationBrand_del__c','Artificial__c','Phone','Fax','Email__c','Website','AuthorityAreas__c','LastYearRevenue__c'};
                fieldsMap.put('Account', accfields);

            }

           



            
        }
    	return fieldsMap;
    }

    public class CompetitorPriceBean{
    	public String oppId ; 
    	public String productLineId ; 
    	public String productLineName ;
    	public String product ; 
    	public String brand ;
    	public String brandId ; 
    	public String agent ; 
    	public String pricesource ; 
    	public String  terprice; 
    	public String  dealerprice; 

    	public CompetitorPriceBean (CompetitorPrice__c cp){
    		product = cp.Product__c;
    		oppId = cp.Opportunities__c;
    		productLineId = cp.ProductLine__c;
    		productLineName = cp.ProductLine__r.ProductLine__c;
    		brand = cp.Manufactor__r.Name;
    		brandId = cp.Manufactor__c;
    		agent = cp.Agent__c;
    		pricesource = cp.PriceSource__c;
    		terprice = cp.TerminalPrice__c;
    		dealerprice = cp.DistributorPrice__c;
    	}
    	public CompetitorPriceBean (IVDProductLineMarket__c ivd ,String opp_id ){
    		oppId  = opp_id;
    		productLineId = ivd.Id;
    		productLineName = ivd.ProductLine__c;

    	}

    }
    public class IntentBean {
    	public String productName ;
    	public String productId ;
    	public String cate0;
    	public String cate1 ;
    	public String spec; 
    	public String serialno ;
    	public String coopmode;
    	public String cpcompany ;
    	public String cpbrand ; 
    	public String cpproduct ;
        public String nccode; 
    	public String brand ;
    	public IntentBean(IntentProduct__c ip ){
    		productName = ip.Product__r.ProductName__c;
    		productId = ip.Product__c;
    		cate0 = ip.Product__r.Category0__c;
    		cate1 = ip.Product__r.Category1__c;
    		spec = ip.Product__r.Spec__c;
    		serialno = ip.Product__r.SerialNo__c;
    		coopmode = ip.ContractForm1__c;
    		cpcompany = ip.CompetitorCompany__c;
    		cpbrand = ip.CompetitorBrand__c;
    		cpproduct = ip.CompetitorProduct__c;
            nccode = ip.Product__r.NCCode__c;
    	}

    	public IntentBean(Product__c p){
    		productName = p.ProductName__c;
    		productId = p.Id; 
    		spec = p.Spec__c;
    		brand  = p.Brand__c ;
    		serialno = p.SerialNo__c;
    		cate0 = p.Category0__c;
    		cate1 = p.Category1__c;
            nccode = p.NCCode__c;


    	}
    }
}